import dayjs from 'dayjs';
// import { handleShipCycle } from '../../utils/index'
import '../../utils/zh-cn'

dayjs.locale('zh-cn')

import { isEmpty } from 'shiptools'

const WEEKDAYS = [0, 1, 2, 3, 4, 5, 6];
Component({
  options: {
      multipleSlots: true, // 在组件定义时的选项中启用多slot支持
      addGlobalClass: true
  },
  /**
   * 组件的属性列表
   */
  properties: {
    className: {
      type: String,
      value: ''
    },
    calConfig: {
      type: Object | Array,
      value: () => {},
      observer: function (newVal, oldVal) { 
        if(newVal !== oldVal && !isEmpty(newVal)) {
          this.init(newVal)
        }
      }
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    months: [],

    weeksHeader: [],
    cycleNotices: [],
    
    isRoundTicket: false
  },

  /**
   * 组件的方法列表
   */
  methods: {
    getMonths: function(initialMonth, numberOfMonths, withoutTransitionMonths) {
      let month = initialMonth.clone();
      if (!withoutTransitionMonths) month = month.subtract(1, 'month');
      let months = [];
      for (let i = 0; i < (withoutTransitionMonths ? numberOfMonths : numberOfMonths + 2); i += 1) {
        month.title = month.format('YYYY年MM月')
        months.push(month);
        month = month.clone().add(1, 'month');

      }
    
      return months;
    },

    getCalendarMonthWeeks: function(
      month,
      enableOutsideDays,
      firstDayOfWeek = 0
    ) {
      if (!dayjs.isDayjs(month) || !month.isValid()) {
        throw new TypeError('`month` must be a valid dayjs object');
      }
      if (WEEKDAYS.indexOf(firstDayOfWeek) === -1) {
        throw new TypeError('`firstDayOfWeek` must be an integer between 0 and 6');
      }
    
      // set utc offset to get correct dates in future (when timezone changes)
      const firstOfMonth = month.clone().startOf('month').hour(12);
      const lastOfMonth = month.clone().endOf('month').hour(12);
    
      // calculate the exact first and last days to fill the entire matrix
      // (considering days outside month)
      const prevDays = ((firstOfMonth.day() + 7 - firstDayOfWeek) % 7);
      const nextDays = ((firstDayOfWeek + 6 - lastOfMonth.day()) % 7);
      const firstDay = firstOfMonth.clone().subtract(prevDays, 'day');
      const lastDay = lastOfMonth.clone().add(nextDays, 'day');
    
      const totalDays = lastDay.diff(firstDay, 'day') + 1;
    
      let currentDay = firstDay.clone();
      const weeksInMonth = [];
      for (let i = 0; i < totalDays; i += 1) {
        if (i % 7 === 0) {
          weeksInMonth.push([]);
        }
    
        let day = null;
        if ((i >= prevDays && i < (totalDays - nextDays)) || enableOutsideDays) {
          day = currentDay.clone();
        }

        const validDay = this._checkDayISAllow(day)

        weeksInMonth[weeksInMonth.length - 1].push(validDay);
    
        currentDay = currentDay.add(1, 'day');
      }
    
      return weeksInMonth;
    },

    // 校验日历 的当前日期是否符合要求
    _checkDayISAllow: function(day) {
      
      const { type, startDate, endDate, saleDays, reserveDays, cycle } = this.properties.calConfig || {}
      
      const _saleDays = Number(saleDays)
      const _reserveDays = Number(reserveDays)

      // 日期范围   是否预约   是否禁用
      const today = dayjs().hour(0).minute(0).second(0)


      // 选择返程日期限制
      const endDateDisAllow = type === 'end' && dayjs(day).isBefore(dayjs(startDate)) && !dayjs(day).isBefore(dayjs(today))
      let isOutStartRange = endDateDisAllow

      // day > today + saleDays - reserveDays && day < today + saleDays
      let isReserve = false
      if(dayjs(day).isAfter(today.add(_saleDays - _reserveDays, 'day')) && dayjs(day).isBefore(today.add(_saleDays, 'day'))) {
        isReserve = true
      }

      // 设置当前出发日期
      let isSelectedStart = false
      if(startDate && startDate === dayjs(day).format('YYYY-MM-DD')) {
        isSelectedStart = true
      }
      
      // 返程日期  如果去程日期大于 返程日期，则不展示返程日期
      let isSelectedEnd = false
      if(endDate && endDate === dayjs(day).format('YYYY-MM-DD') && !dayjs(startDate).isAfter(endDate)) {
        isSelectedEnd = true
      }

      
      // day < today && day > today + saleDays
      let isOutRange = false

      // 如果是往返票，并且选择了返程，则 去程之前的日期是不可选的
      if(dayjs(day).isBefore(dayjs(today)) || dayjs(day).isAfter(today.add(_saleDays, 'day'))) {
        isOutRange = true
      }
     


      // 发船周期
      let isOutCycle = false
      if(!cycle.includes(dayjs(day).day())) {
        isOutCycle = true
      }

      return {
        day: day? day.format('D'): '',
        format: day && day.format('YYYY-MM-DD'),
        isOutRange,
        isReserve,
        isOutCycle,
        disabled: isOutRange || isOutStartRange || isOutCycle,
        isSelectedStart,
        isSelectedEnd,

        isOutStartRange
      }
    },
    

    // 以下是旧式的定义方式，可以保持对 <2.2.3 版本基础库的兼容
    
    init: function(config) {
      const that = this
      const { saleDays, isRound, cycle } = config || {}
      const numOfMonth = Math.ceil(((Number(saleDays) || 30) + dayjs().date()) / 30);
      const months = this.getMonths(dayjs(), numOfMonth, true)

      months.forEach(month => {
        const weeksInMonth = that.getCalendarMonthWeeks(month, false, 0)
        month.weeks = weeksInMonth
      })

      let weeksHeader = WEEKDAYS.map(item => {
        const firstDayOfWeek = 0
        const weekDayFormat = 'dd'
        return dayjs().day((item + firstDayOfWeek) % 7).format(weekDayFormat)
      })  

      const isRoundTicket = isRound
      let cycleNotices = []
      if(cycle.length < 7) {

      }

      this.setData({
        months,
        weeksHeader,
        isRoundTicket
      })
    },


    onChooseDay: function(e) {
      const day = e.currentTarget.dataset.day
      const { type } = this.properties.calConfig || {}
      if(day.disabled) return
      this.triggerEvent('choose', {
        type,
        format: day.format
      })
    }
  },
  
  lifetimes: {
    
    attached: function() {
      const that = this
      // 在组件实例进入页面节点树时执行
      // setTimeout(() => {
      //   that.init()
      // }, 10)
    },
    detached: function() {
      // 在组件实例被从页面节点树移除时执行
    },
  
    error: function() {
      this.setData({
        errorState: true
      })
    }
  }
  

})
